#ifndef FC46A0B8_2322_4FE4_801D_F62D376D0EC6
#define FC46A0B8_2322_4FE4_801D_F62D376D0EC6

#include <vector>
#include <string>
#include <mutex>
#include <map>
#include <memory>
#include "subscriber.h"

namespace cores
{
    namespace topics
    {
        class Publisher;

        /**
         * @brief 主题管理，管理主题的订阅者
         * 
         */
        class Topic
        {
        private:
            /**
             * @brief 互斥锁
             * 
             */
            std::mutex _mutex;

            /**
             * @brief 主题名
             * 
             */
            std::string _topic;

            /**
             * @brief 订阅者列表
             * 
             */
            std::vector<Subscriber*> _subscribers;

        public:
            /**
             * @brief 构造函数
             * 
             * @param topic 主题名称
             */
            Topic(const std::string& topic);

            /**
             * @brief 析构函数
             * 
             */
            virtual ~Topic();

            /**
             * @brief 添加订阅者
             * 
             * @param subscriber 订阅者对象
             */
            void append(Subscriber * subscriber);

            /**
             * @brief 删除订阅者
             * 
             * @param subscriber 订阅者对象
             */
            void remove(Subscriber * subscriber);

            /**
             * @brief 发布主题
             * 
             * @tparam T 数据类型
             * @param sender 发布者对象
             * @param value 主题数据
             */
            template <typename T>
            void publish(Publisher * sender, const T& value)
            {
                std::unique_lock<std::mutex> lock(_mutex);
                for (auto subscriber : _subscribers)
                {
                    ISubscribeImpl<T>* impl = subscriber->getSubscribeImpl<T>();
                    if (impl == nullptr)
                        continue;

                    impl->onDataReceived(sender, _topic, value);
                }
            }
        };

        /**
         * @brief 主题中心
         * 
         */
        class BASE_EXPORT TopicsCenter
        {
        private:
            /**
             * @brief 主题名+主题管理对象键值对
             * 
             */
            std::map<std::string, std::shared_ptr<Topic>> _mapTopics;

            /**
             * @brief 主题中心，单例模式
             * 
             */
            static TopicsCenter globalInstance;

        protected:
            /**
             * @brief 构造函数
             * 
             */
            TopicsCenter();

        public:
            /**
             * @brief 析构函数
             * 
             */
            virtual ~TopicsCenter();

            /**
             * @brief 获取主题中心实例
             * 
             * @return TopicsCenter* 
             */
            static TopicsCenter* Instance();

            /**
             * @brief 订阅者订阅主题
             * 
             * @param topic 主题
             * @param subscriber 订阅者对象 
             */
            void subscribe(const std::string& topic, Subscriber * subscriber);

            /**
             * @brief 订阅者退订主题
             *  
             * @param topic 主题 
             * @param subscriber 订阅者对象 
             */
            void unsubscribe(const std::string& topic, Subscriber * subscriber);

            /**
             * @brief 发布者发布主题数据
             * 
             * @tparam T 
             * @param sender 
             * @param topic 
             * @param value 
             */
            template <typename T>
            void publish(Publisher * sender, const std::string& topic, const T& value)
            {
                if (_mapTopics.count(topic) == 0 || _mapTopics[topic].get() == nullptr)
                    return;

                _mapTopics[topic]->publish<T>(sender, value);
            }
        };
    }
}

#endif /* FC46A0B8_2322_4FE4_801D_F62D376D0EC6 */
